package org.study.seatatcc.stock.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.seata.core.context.RootContext;
import org.apache.seata.rm.tcc.api.BusinessActionContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.study.seatatcc.stock.entity.Stock;
import org.study.seatatcc.stock.mapper.StockMapper;

/**
 * 作用描述
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2024年01月25日
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements StockService {
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void deduct(String commodityCode, int count) {
        log.info("StockService XID = {}", RootContext.getXID());
        QueryWrapper<Stock> wrapper = new QueryWrapper<>();
        wrapper.setEntity(new Stock().setCommodityCode(commodityCode));
        Stock stock = baseMapper.selectOne(wrapper);
        stock.setCount(stock.getCount() - count);
        baseMapper.updateById(stock);
        if (commodityCode.equals("product-2")) {
            throw new RuntimeException("异常:模拟业务异常:stock branch exception");
        }
    }

    @Override
    public boolean busCommit(BusinessActionContext actionContext) {
        log.info("busCommit xid = " + actionContext.getXid() + "提交成功");
        return true;
    }

    @Override
    public boolean busRollback(BusinessActionContext actionContext) {
        // 编写对应的业务数据进行回滚
        String commodityCode = actionContext.getActionContext("commodityCode", String.class);
        int count = actionContext.getActionContext("count", Integer.class);
        LambdaQueryChainWrapper<Stock> eq = lambdaQuery().eq(Stock::getCommodityCode, commodityCode);
        Long count1 = eq.one().getCount();
        // 扣了多少数，需要重新添加回去
        lambdaUpdate().set(Stock::getCount, count + count1)
                .eq(Stock::getCommodityCode, commodityCode)
                .update();
        log.info("busRollback xid = " + actionContext.getXid() + "回滚成功");
        return true;
    }
}
